/******************************************************************************
* This file is part of is32p218 platform,
* Copyright (c) 2009 HangZhou InfoStrong CO.,LTD. All rights reserved.
* This software may only be used under the terms of a valid, current,
* end user license from InfoStrong.
* Nothing else gives you the right to use this software.   
*
* Name:   app_plc.c
* Desc:   PLC Application layer procedure C file
* Author: Jerry
* Date:   2009-10-30
* Note:   
* History:
*
******************************************************************************/
#include <string.h>
#include "drv_all.h"
#include "os_api.h"
#include "app.h"
#include "app_afn.h"
#include "app_plc.h"
#include "mw_nram.h"
#include "plc_all.h"
#include "xn5106x.h"
#include "mw_rst_ctrl.h"

#define PLC_PARA_FIXED				0		// Fixed in source-code

APP_PLC_CTRL g_app_plc_ctrl;
#if (defined(ZCP_DET_AUTO_SEL)&&(defined(XN5106C_EXT)))
static void app_plc_tmout_proc( void *p_arg );
#endif


#if (defined(ZCP_DET_AUTO_SEL)&&(defined(XN5106C_EXT)))

/*
* Function Name:
*   app_plc_zcp_det_sel
* Description:
*   ZCP detect selection
* Parameters:
*   IO_ZCP_DET io_zcp_det: 
* Returns:
*   None
* Author				Date 
*  Jerry				2011-4-22   
* Note:
*    P00,P01 = 00  Phase A
*    P00,P01 = 10  Phase B
*    P00,P01 = 01  Phase C
*/
const U8 c_app_plc_zcp_det_tbl[] = 
{
	0x00,
	0x02,
	0x01
};

void app_plc_zcp_det_sel( IO_ZCP_DET io_zcp_det )
{
#ifdef PHASE_SEQ_24_FLG
	U32 cpu_sr; 
#endif
	// @@@@@@new000012 jerry, on 2012-9-12 --- begin
#ifdef MW_RST_CTRL
	mw_rst_ctrl_data_write( RST_CTRL_DATA_ZCP_SEL, &io_zcp_det, 1 );
#endif
	// @@@@@@new000012 jerry, on 2012-9-12 --- end

#ifdef PHASE_SEQ_24_FLG
	isOS_ENTER_CRITICAL( cpu_sr ); 
	rP0 = (rP0&0xFC)|c_app_plc_zcp_det_tbl[io_zcp_det];
	isOS_EXIT_CRITICAL( cpu_sr );
#else
	if( IO_ZCP_DET_A == io_zcp_det && 0x03 == (rP0FUN_SEL&0x03) )
	{	// P00, P01 is used to GPIO, PLC select Phase A to ZCP_DET
		return;
	}
	rP0FUN_SEL = (rP0FUN_SEL&0xFC)|io_zcp_det;
#endif
}

/*
* Function Name:
*   app_plc_tmout_proc
* Description:
*   
* Parameters:
*   void* p_arg:
* Returns:
*   :
* Author				Date 
*  Jerry				2011-5-9   
* Note:
*    
*/
static void app_plc_tmout_proc( void *p_arg )
{
	APP_PLC_TMR_ID_T tmr_id;

	tmr_id = (APP_PLC_TMR_ID_T)((U32)p_arg);
#if (defined(ZCP_DET_AUTO_SEL)&&(defined(XN5106C_EXT)))
	switch(tmr_id)
	{
		case APP_PLC_TMR_ID_ZCP_DET_CHK:
		{
			if ( !plc_pl_timing_ok_chk() )
			{
				g_app_plc_ctrl.m_zcp_det_cnt++;
				if( g_app_plc_ctrl.m_zcp_det_cnt>=ZCP_DET_CHK_ERR_CNT_MAX )
				{
					g_app_plc_ctrl.m_zcp_x = (IO_ZCP_DET)((g_app_plc_ctrl.m_zcp_x<IO_ZCP_DET_C) \
						?(g_app_plc_ctrl.m_zcp_x+1):(IO_ZCP_DET_A));
					app_plc_zcp_det_sel( g_app_plc_ctrl.m_zcp_x );

					g_app_plc_ctrl.m_zcp_det_cnt = 0;
				}
			}
			else
			{
				g_app_plc_ctrl.m_zcp_det_cnt = 0;
			}

			isOS_TmrSetExpireTick( &g_app_plc_ctrl.m_zcp_det_tmr, ZCP_DET_CHK_TMR_INTERVAL );
			isOS_TmrStart( &g_app_plc_ctrl.m_zcp_det_tmr );
			break;
		}
	
	}
#endif
}
#endif

#ifdef PHASE_SEQ_24_FLG
/*
* Function Name:
*   app_plc_phase_det_set
* Description:
*   
* Parameters:
*   BOOL flg:
* Returns:
*   :
* Author				Date 
*  Jerry				2011-12-7   
* Note:
*    
*/
void app_plc_phase_det_set( BOOL flg )
{
	plc_if_phase_det_flg_set( flg );
}
#endif

/*
* Function Name:
*   app_plc_start
* Description:
*   Start PLC module&protocol
* Parameters: 
*    U8 *p_mac_addr: mac address 
* Returns:
*   BOOL:
* Author				Date 
*  Jerry				2010-4-16   
* Note:
*    
*/
static BOOL app_plc_start( U8 *p_mac_addr )
{
	PLC_HL_INIT_DATA_T *p_hl_init;

	p_hl_init = (PLC_HL_INIT_DATA_T *)sys_malloc( sizeof(PLC_HL_INIT_DATA_T) );
	if ( NULL==p_hl_init )
	{
		IS_ASSERT(0);
		return FALSE;
	}
	p_hl_init->m_mode = PLC_HL_MODE_SLAVE;

#if PLC_PARA_FIXED
	isOS_memcpy( (U8*)&p_hl_init->m_params, (U8*)plc_if_params_default_get(), \
				 sizeof(PLC_PARAMS_T) );
#else
	if ( !bu_mw_Nram_read( NRAM_ITEM_PLC_PARAMS, 0, sizeof(PLC_PARAMS_T), (U8*)&p_hl_init->m_params ) )
	{
		isOS_memcpy( (U8*)&p_hl_init->m_params, (U8*)plc_if_params_default_get(), \
					 sizeof(PLC_PARAMS_T) );
		IS_ASSERT(0);
	}
#endif

	isOS_memcpy( (U8*)p_hl_init->m_mac, (U8*)p_mac_addr, MAC_ADDR_LEN );

#if (defined(PLC_MAC_BIND)||defined(PLC_VOID_COLLUDE))
	if ( !bu_mw_Nram_read( NRAM_ITEM_PLC_DC_MAC, 0, PLC_PH_MAC_LEN, (U8*)p_hl_init->m_dc_mac ) )
	{	// Set invalidate DC MAC( 0xFFFFFFFFFFFF )
		isOS_memcpy( (U8*)p_hl_init->m_dc_mac, c_plc_mac_empty, PLC_PH_MAC_LEN );
//		bu_mw_Nram_write( NRAM_ITEM_PLC_DC_MAC, 0, (U8*)p_hl_init->m_dc_mac, PLC_PH_MAC_LEN );
	}
#endif

	// Start PLC protocol
	if ( FALSE == plc_msg_snd( MSG_AFN_TO_PLC_INIT, (U8*)p_hl_init, \
								sizeof(PLC_HL_INIT_DATA_T) ) )
	{
		sys_free( (U8*)p_hl_init );
		IS_ASSERT(0);
		return FALSE;
	}
	return TRUE;
}

/*
* Function Name:
*   app_plc_init
* Description:
*   app plc init
* Parameters: 
*    U8 *p_mac_addr: mac address  
* Returns:
*   BOOL:
* Author				Date 
*  Jerry				2011-5-9   
* Note:
*    
*/
BOOL app_plc_init( U8 *p_mac_addr )
{
#if (defined(ZCP_DET_AUTO_SEL)&&(defined(XN5106C_EXT)))
	S32 ret;
	ret = isOS_TmrCreate( &g_app_plc_ctrl.m_zcp_det_tmr, 100, app_plc_tmout_proc, \
						  (void*)APP_PLC_TMR_ID_ZCP_DET_CHK, "App PLC Timer" );
	ret = ret;

	g_app_plc_ctrl.m_zcp_x = IO_ZCP_DET_A;
	// @@@@@@new000012 jerry, on 2012-9-12 --- begin
#ifdef MW_RST_CTRL
	if ( mw_rst_ctrl_type()==RST_CTRL_TYPE_HOT )
	{
		U8 zcp_x = IO_ZCP_DET_A;
		mw_rst_ctrl_data_read( RST_CTRL_DATA_ZCP_SEL, &zcp_x, sizeof(zcp_x) );
		g_app_plc_ctrl.m_zcp_x = (IO_ZCP_DET)zcp_x;
	}
#endif
	// @@@@@@new000012 jerry, on 2012-9-12 --- end

#ifdef PHASE_SEQ_24_FLG
	drv_sys_port0_setfunc( P00, IO_FUNC_IO );
	drv_sys_port0_setfunc( P01, IO_FUNC_IO );
	drv_sys_port0_setmod( P00, IO_OUTPUT );
	drv_sys_port0_setmod( P01, IO_OUTPUT );
#endif
	app_plc_zcp_det_sel(g_app_plc_ctrl.m_zcp_x);

	isOS_TmrSetExpireTick( &g_app_plc_ctrl.m_zcp_det_tmr, ZCP_DET_CHK_TMR_INTERVAL_FIRST );
	isOS_TmrStart( &g_app_plc_ctrl.m_zcp_det_tmr );
#endif

	app_plc_start( p_mac_addr );			// PLC Start
	return TRUE;
}

